
/**
  ******************************************************************************
  * Copyright 2021 The grapilot Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       gp_vector2.c
  * @author     baiyang
  * @date       2021-7-6
  ******************************************************************************
  */

/*----------------------------------include-----------------------------------*/
#include "gp_vector2.h"
#include "gp_math.h"
/*-----------------------------------macro------------------------------------*/

/*----------------------------------typedef-----------------------------------*/

/*---------------------------------prototype----------------------------------*/

/*----------------------------------variable----------------------------------*/

/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/
/** 
  * @brief       二维向量设置值
  * @param[in]   vo  
  * @param[in]   x  
  * @param[in]   y  
  * @param[out]  
  * @retval      
  * @note        
  */
void vec2_set(Vector2f_t* vo, const float x, const float y)
{
    vo->x = x;
    vo->y = y;
}

/** 
  * @brief       二维向量元素初始化为0
  * @param[in]   vo  
  * @param[out]  
  * @retval      
  * @note        
  */
void vec2_zero(Vector2f_t* vo)
{
    vo->x = 0.0f;
    vo->y = 0.0f;
}

/** 
  * @brief       二维向量求模
  * @param[in]   v  
  * @param[out]  
  * @retval      
  * @note        
  */
float vec2_length(const Vector2f_t* v)
{
    return sqrtf(v->x * v->x + v->y * v->y);
}

/** 
  * @brief       计算三维向量模值的平方
  * @param[in]   v  
  * @param[out]  
  * @retval      
  * @note        
  */
float vec2_length_squared(const Vector2f_t* v)
{
    return v->x * v->x + v->y * v->y; 
}

// limit vector to a given length. returns true if vector was limited
bool vec2_limit_length(Vector2f_t* v, float max_length)
{
    const float len = vec2_length(v);
    if ((len > max_length) && math_flt_positive(len)) {
        v->x *= (max_length / len);
        v->y *= (max_length / len);
        return true;
    }
    return false;
}

/** 
  * @brief       二维向量单位化
  * @param[in]   vo  
  * @param[in]   vi  
  * @param[out]  
  * @retval      
  * @note        
  */
void vec2_norm(Vector2f_t* vo, const Vector2f_t* vi)
{
    float len = vec2_length(vi);
    if(math_flt_zero(len))
    {
        vec2_zero(vo);
    }
    else
    {
        vo->x = vi->x / len;
        vo->y = vi->y / len;
    }  
}

/**
  * @brief       
  * @param[in]   v  
  * @param[out]  
  * @retval      
  * @note        
  */
Vector2f_t vec2_normalized(const Vector2f_t* v)
{
    Vector2f_t vo;
    float len = sqrtf(v->x * v->x + v->y * v->y);

    vo.x = v->x / len;
    vo.y = v->y / len;

    return vo;
}

/** 
  * @brief       二维向量求和
  * @param[in]   vo  
  * @param[in]   v1  
  * @param[in]   v2  
  * @param[out]  
  * @retval      
  * @note        
  */
void vec2_add(Vector2f_t* vo, const Vector2f_t* v1, const Vector2f_t* v2)
{
    vo->x = v1->x + v2->x;
    vo->y = v1->y + v2->y;
}

/** 
  * @brief       二维向量减运算
  * @param[in]   vo  
  * @param[in]   v1  
  * @param[in]   v2  
  * @param[out]  
  * @retval      
  * @note        
  */
void vec2_sub(Vector2f_t* vo, const Vector2f_t* v1, const Vector2f_t* v2)
{
    vo->vec2[0] = v1->vec2[0] - v2->vec2[0];
    vo->vec2[1] = v1->vec2[1] - v2->vec2[1]; 
}

/** 
  * @brief       二维向量×运算 sin
  * @param[in]   v1  
  * @param[in]   v2  
  * @param[out]  
  * @retval      
  * @note        
  */
float vec2_cross(const Vector2f_t* v1, const Vector2f_t* v2)
{
    return v1->vec2[0] * v2->vec2[1] - v1->vec2[1] * v2->vec2[0];
}

/** 
  * @brief       二维向量点乘 cos
  * @param[in]   v1  
  * @param[in]   v2  
  * @param[out]  
  * @retval      
  * @note        
  */
float vec2_dot(const Vector2f_t* v1, const Vector2f_t* v2)
{
    return v1->vec2[0] * v2->vec2[0] + v1->vec2[1] * v2->vec2[1];
}

/** 
  * @brief       二维向量运放
  * @param[in]   vo  
  * @param[in]   vi  
  * @param[in]   scalar  
  * @param[out]  
  * @retval      
  * @note        
  */
void vec2_mult(Vector2f_t* vo, const Vector2f_t* vi, const float scalar)
{
    vo->vec2[0] = vi->vec2[0] * scalar;
    vo->vec2[1] = vi->vec2[1] * scalar;
}
/*------------------------------------test------------------------------------*/


